<?php

/**
 * 付款单管理
 */

namespace app\admin\service;

use app\admin\model\Images;
use app\admin\model\PurchaseOrders;
use app\admin\model\PurchasePaymentOrder;
use app\common\Common;
use Exception;
use think\facade\Config;
use think\facade\Db;
use think\facade\Env;
use think\Service;
use app\admin\model\PurchasePaymentOrder as PaymentModel;
use app\admin\model\PurchaseOrdersDetail as PurchaseOrdersDetailModel;
use app\common\service\DingTalk as DingTalkService;
use app\admin\model\Operator as OperatorModel;
use app\common\service\CompleteNotificationService;

class Payment extends BaseService
{

    /**
     * 获取付款单列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($param = [], $page = 1, $limit = 10)
    {
        $where = [['db_purchase_payment_order.is_del', '=', 0]];
        $arrData = ['code' => 0, 'message' => 'success'];
        if ($param['payno']) {
            $where[] = ['payno', 'like', '%' . $param['payno'] . '%'];
        }
        $purchaseWhere = [];
        if ($param['purchase_no']) {
            $purchaseWhere[] = ['purchase_no', 'like', '%' . $param['purchase_no'] . '%'];
        }
        if (!is_null($param['status'])) {
            $where[] = ['db_purchase_payment_order.status', '=', $param['status']];
        }

        $oPaymentModel = PaymentModel::where($where)->hasWhere('purchaseOrderNo', function ($query) use ($purchaseWhere) {
            $query->where($purchaseWhere);
        });
        $total = $oPaymentModel->count();
        $result = $oPaymentModel
            ->with(['get_owner_value', 'get_responsible_value', 'purchase_order_no'])
            ->append(['pay_type_value', 'status_value', 'payment_account_value', 'total_amount'])
            ->page($page, $limit)
            ->order('id', 'desc')
            ->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 删除单条或多条付款单数据
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete($param)
    {
        $where = [['is_del', '=', '0'],['creator', '=', $param['operator_id']], ['id', 'in', $param['ids']], ['status', 'in', [1,4]]];

        $oPaymentModel = PaymentModel::where($where);
        $purchase = $oPaymentModel->find();
        if (!$purchase) {
            return ['code' => 1, 'message' => '获取付款单信息失败！'];
        }
        $result = $oPaymentModel->update(['is_del' => time(),'status'=>8]);
        PurchaseOrdersDetailModel::whereIn('orderid', $param['ids'])->delete();
        if ($result) {
            $this->logger->logOperation($param['ids'], 'purchase_payment_order', '采购付款单-删除', '删除单条或多条付款单数据');
            return ['code' => 0, 'message' => '删除付款单成功！'];
        } else {
            return ['code' => 1, 'message' => '删除付款单失败！'];
        }
    }

    /**
     * 添加修改付款单
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save($param)
    {
        Db::startTrans();
        try {
            $oCommon = new Common();

            $payno = $oCommon->generateOrderNo($param['operator_id']);
            $purchase = PurchaseOrders::where('id', $param['purchaseid'])->find();

            if (!$payno) {
                throw new Exception("生成订单号失败!");
            }

            $checkPaymentModel = PaymentModel::where([['payno', '=', $payno], ['is_del', '=', 0]]);
            if ($param['id']) {
                $checkPaymentModel->where('id', '<>', $param['id']);
            }
            if ($checkPaymentModel->find()) {
                throw new Exception("支付订单号重复!");
            }

            if ($param['id']) {
                $oPaymentModel = PaymentModel::find($param['id']);
                $oPaymentModel->updater = $param['operator_id'];
                $oPaymentModel->update_time = date('Y-m-d H:i:s', time());
            } else {
                $oPaymentModel = new PaymentModel();
                $oPaymentModel->creator = $param['operator_id'];
                $oPaymentModel->create_time = date('Y-m-d H:i:s', time());
                $oPaymentModel->is_del = 0;
                $oPaymentModel->status = 1;
                $oPaymentModel->pay_status = 0;
            }
            $oPaymentModel->payno = $payno;
            $oPaymentModel->currency = $purchase->currency;
            $oPaymentModel->pay_amount = $param['pay_amount'];
            $oPaymentModel->purchaseid = $param['purchaseid'];
            $oPaymentModel->owner = $param['owner'];
            $oPaymentModel->payment_date = $param['payment_date'];
            $oPaymentModel->payment_account = $param['payment_account'];
            $oPaymentModel->pay_type = $param['pay_type'];
            $oPaymentModel->recipient_account = $param['recipient_account'];
            $oPaymentModel->remark = $param['remark'];
            $oPaymentModel->attachment = $param['attachment'];
            $oPaymentModel->responsible = $param['responsible'];

            if (!$oPaymentModel->save()) {
                throw new Exception("付款单保存失败!");
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        $contract_no = $purchase->contract_no;

        $pay_type = (new PaymentModel())->getAttributes('pay_type')[$oPaymentModel->pay_type] ?? '';

        $operator = \app\admin\model\Operator::where('id',$param['operator_id'])->value('cname');

        /* 发送工作通知 */
        $title = $operator.'提交了一个付款单';
        $content = "付款单: {$oPaymentModel->payno} \n\n  关联采购合同：{$contract_no}\n\n  付款金额：{$oPaymentModel->pay_amount} \n\n 支付方式：{$pay_type}";
        $url = Config::get('domain.' . Env::get('APP_ENV') . '.erphome') . '/#/purchase/payment-order-management/proof?id=' . $oPaymentModel->id;

        /* 获取接收信息用户ID */
        $PurchasePaymentOrder = new PurchasePaymentOrder();
        $PayTypeMessageGroup = $PurchasePaymentOrder->getPayTypeGroupEnum($oPaymentModel->pay_type);

        /* 获取用户ID */
        $query = OperatorModel::query();
        $query->where('is_del', '=', '0');
        $query->where(function ($query) use ($PayTypeMessageGroup) {
            foreach ($PayTypeMessageGroup as $id) {
                $query->whereOrRaw('FIND_IN_SET(?, job)', [$id]);
            }
        });

        $operatorIDList = $query->column('id');
        if (!$operatorIDList) {
            return ['code' => 1, 'message' => '发送通知用户不存'];
        }

        /* 发送通知 */
        $DingTalkService = new DingTalkService();
        $DingTalkService->SendActioncardJobNotificationMessage($title, $content, $url, $operatorIDList);

        $this->logger->logOperation($oPaymentModel->id, 'purchase_payment_order', '采购付款单-创建', '添加/修改付款单',1,'purchase_payment_order',$oPaymentModel->id,implode(',',$PayTypeMessageGroup));
        return ['code' => 0, 'message' => '保存付款单成功！'];
    }

    /**
     * 获取单个付款单信息
     * @param int $id 付款单ID
     * @return array
     */
    public function getInfo($param)
    {
        $where = [['is_del', '=', '0'], ['id', '=', $param['id']]];
        $oPaymentModel = PaymentModel::where($where)->with(['get_owner_value', 'get_responsible_value', 'getAttachment', 'purchase_order_no'])
            ->append(['pay_type_value', 'status_value', 'payment_account_value'])->find();
        if (!$oPaymentModel) {
            return ['code' => 1, 'message' => '获取付款单信息失败！'];
        }
        $data = $oPaymentModel->toArray();
        $attachment_id = $data['attachment'] ? explode(',', $data['attachment']) : [];

        $data['attachment'] = $attachment_id;
        $oImages = new Images();
        $imageData = $oImages->getImagesByIds($attachment_id);
        $data['attachment_urls'] = $imageData;
        $proof_id = $data['proof'] ? explode(',', $data['proof']) : [];
        $oImages = new Images();
        $proofData = $oImages->getImagesByIds($proof_id);
        $data['proof_urls'] = $proofData;


        $data['total_amount'] = number_format($data['product_total_amount'] + $data['other_amount'], 2);


        return ['code' => 0, 'message' => 'success', 'data' => $data];
    }

    public function getFieldEnum($field)
    {
        $model = new PaymentModel();
        $res = $model->getFieldEnum($field);
        return [
            'code' => 0,
            'data' => $res
        ];
    }

    /**
     * 付款单审核
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function examine($param)
    {
        $where = [
            ['id', '=', $param['id']],
            ['is_del', '=', 0],
            ['status', '=', 1]
        ];
        $oPaymentModel = PaymentModel::where($where)->find();
        if (!$oPaymentModel) {
            return ['code' => 1, 'message' => '获取付款单信息失败！'];
        }
        $oPaymentModel->status = 8;
        if($param['status'] == 1){
            $oPaymentModel->status = 20;
            //        $oPaymentModel->info = $param['info'];
        }
        if ($oPaymentModel->save()) {
            $approverWhere = [
                'entity_id' => $param['id'],
                'business_module' => 'purchase_payment_order',
                'operate' => '采购付款单-创建',

            ];
            $this->logger->updateApprover($approverWhere,$param['operator_id']);
            $this->logger->logOperation($param['id'], 'purchase_payment_order', $param['status'] == 1?'采购付款单-审核通过':'采购付款单-审核驳回', '付款单审核');
            return ['code' => 0, 'message' => '付款单审核成功！'];
        }
    }

    /**
     * 上传支付凭证
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function proof($param)
    {
        Db::startTrans();
        try {
            $where = [
                ['id', '=', $param['id']],
                ['is_del', '=', 0],
                ['status', '=', 20]
            ];
            $oPaymentModel = PaymentModel::where($where)->find();
            if (!$oPaymentModel) {
                throw new Exception("获取付款单信息失败！");
            }

            $oPaymentModel->status = 30; //已上传凭证
            $oPaymentModel->proof = $param['proof']; //凭证数据
            $oPaymentModel->hash = $param['hash']; //凭证数据
            if (!$oPaymentModel->save()) {
                throw new Exception("上传支付凭证失败！");
            }
            // todo 添加操作日志

            // 获取采购单数据
            $oPurchaseOrders = PurchaseOrders::where('id', $oPaymentModel->purchaseid)->find();

            // 判断是否完成全部付款
            $total_paid = PaymentModel::where([['purchaseid', '=', $oPaymentModel->purchaseid], ['status', '=', 30]])->sum('pay_amount');
            if ($total_paid >= ($oPurchaseOrders->product_total_amount + $oPurchaseOrders->other_amount)) {
                // 更新采购单支付状态
                $oPurchaseOrders->pay_status = 2;
                $oPurchaseOrders->pay_time = date('Y-m-d H:i:s');
            } else {
                $oPurchaseOrders->pay_status = 1;
            }

            // 更新采购单状态
            $oPurchaseOrders->pay_amount = $oPurchaseOrders->pay_amount + $oPaymentModel->pay_amount;
            $purchaseService = new Purchase();
            $is_have_no_receipt = $purchaseService->checkHaveNoReceipt($oPurchaseOrders->id);
            if ($is_have_no_receipt) { //还有待入库的商品，则采购单状态为待入库
                $oPurchaseOrders->status = 30;
            }
            if (!$oPurchaseOrders->save()) {
                throw new Exception("更新采购单状态失败！");
            }
            Db::commit();
            $owner = $oPaymentModel->owner ?? null;
            $responsible = $oPaymentModel->responsible ?? null;
            $notificationService = new CompleteNotificationService();
            $res = $notificationService->send('purchase_payment_examine', $oPaymentModel->toArray(), [$owner, $responsible], '您有一条采购付款单审核通过，请及时处理');
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        $this->logger->logOperation($param['id'], 'Payment', '上传', '上传支付凭证');
        return ['code' => 0, 'message' => '付款单审核成功！'];
    }

    public function get_unique_str()
    {
        $currentDate = date('Ymd');
        $uniqueIdentifier = uniqid('');
        $finalCode = $currentDate . $uniqueIdentifier;
        return $finalCode;
    }
}
